
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
# import backtrader as bt
# import pandas as pd
# import matplotlib.pyplot as plt


import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])
sys.path.append('./backtrader')
# Import the backtrader platform
import backtrader as bt
class SmaCrossStrategy(bt.Strategy):
    params = (
        ('fast', 10),  # 快速均线周期
        ('slow', 30),  # 慢速均线周期
        ('printlog', True),
    )

    def __init__(self):
        sma_fast = bt.ind.SMA(period=self.p.fast)
        sma_slow = bt.ind.SMA(period=self.p.slow)
        self.crossover = bt.ind.CrossOver(sma_fast, sma_slow)
        self.dataclose = self.datas[0].close

    def next(self):
        if not self.position:
            if self.crossover > 0:  # 金叉买入
                self.order = self.buy(size=100)
        elif self.crossover < 0:  # 死叉卖出
            self.order = self.sell(size=100)

    def log(self, txt, dt=None, doprint=False):
        if self.params.printlog or doprint:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()},{txt}')

    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            return
        if order.status == order.Completed:
            if order.isbuy():
                self.log(f'买入执行, 价格:{order.executed.price:.2f}, 成本:{order.executed.value:.2f}, 佣金:{order.executed.comm:.2f}')
            elif order.issell():
                self.log(f'卖出执行, 价格:{order.executed.price:.2f}, 金额:{order.executed.value:.2f}, 佣金:{order.executed.comm:.2f}')
data_path_global = './csv_data/SH_000300_stock_data.csv'
if __name__ == '__main__':
    cerebro = bt.Cerebro()
    
    # 加载沪深300ETF数据（示例：510300.SH）
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    datapath = os.path.join(modpath, data_path_global)

    # Create a Data Feed
    data = bt.feeds.YahooFinanceCSVData(
        dataname=datapath,
        # Do not pass values before this date
        fromdate=datetime.datetime(2023, 8, 3),
        # Do not pass values after this date
        todate=datetime.datetime(2025, 9, 5),
        # Do not pass values after this date
        reverse=False)
    cerebro.adddata(data)
    
    # 策略配置
    cerebro.addstrategy(SmaCrossStrategy)
    cerebro.broker.setcash(100000)
    cerebro.broker.setcommission(commission=0.0003)  # 万3佣金
    
    # 添加分析器
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
    cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='annual')
    
    print('初始资金: %.2f' % cerebro.broker.getvalue())
    results = cerebro.run()
    print('最终资金: %.2f' % cerebro.broker.getvalue())
    
    # 输出绩效指标
    strat = results[0]
    print('夏普比率:', strat.analyzers.sharpe.get_analysis()['sharperatio'])
    print('最大回撤:', strat.analyzers.drawdown.get_analysis()['max']['drawdown'])
    
    # 绘制结果
    # cerebro.plot(style='candlestick')
